﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenVision.Models;
using System.Data.Entity;

namespace OpenVision.Repositories
{
    public class DbCollarsRepository : ICollarRepository
    {
        public DbCollarsRepository(DbContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("Invalid database context! It cannot be null!");
            }

            this.Context = context;
            this.DbSet = this.Context.Set<Collar>();
            this.DbUsers = this.Context.Set<User>();
            this.DbSetChanges = this.Context.Set<Change>();
        }

        protected DbContext Context { get; set; }

        protected DbSet<Collar> DbSet { get; set; }

        protected DbSet<User> DbUsers { get; set; }

        protected DbSet<Change> DbSetChanges { get; set; }

        public void UpdatePosition(double longitude, double latitude, int id)
        {
            if (id < 0)
            {
                throw new ArgumentOutOfRangeException("Id must be positive integer number!");
            }

            var collar = this.DbSet.Where(x => x.Id == id).FirstOrDefault();

            collar.Longitude = longitude;
            collar.Latitude = latitude;

            var changes = this.DbSetChanges.Where(x => x.Leash.Id == collar.Id);

            foreach (var change in changes)
            {
                change.HasCollarPositionChanged = true;
            }

            this.Context.SaveChanges();
        }

        public Collar GetPosition(string sessionKey)
        {
            var dbUser = this.DbUsers.Where(x => x.SessionKey == sessionKey).FirstOrDefault();
            var dbCollar = this.DbSet.Where(x => x.User.Id == dbUser.Id).FirstOrDefault();

            return dbCollar;
        }

        public ChangesUpdates CheckForChanges(int id)
        {
            var changes = this.DbSetChanges.Where(x => x.Leash.Id == id).FirstOrDefault();

            ChangesUpdates changesModel = new ChangesUpdates();

            if (changes.HasUserPositionChanged)
            {
                changesModel.Longitude = changes.User.Longitude;
                changesModel.Latitude = changes.User.Latitude;
                changes.HasUserPositionChanged = false;
            }
            
            if (changes.HasUserRangeChanged)
            {
                changesModel.Range = changes.User.Range;
                changes.HasUserRangeChanged = false;
            }
            
            if (changes.HasSoundMessageChanged)
            {
                changesModel.SoundMessage = changes.User.SoundMessage;
                changes.HasSoundMessageChanged = false;
            }

            if (changes.HasTheCallButtonPressed)
            {
                changesModel.IsCalled = true;
                changes.HasTheCallButtonPressed = false;
            }

            this.Context.SaveChanges();

            return changesModel;
        }

        public IQueryable<Collar> All()
        {
            throw new NotImplementedException();
        }

        public Collar Get(int id)
        {
            if (id < 0)
            {
                throw new ArgumentOutOfRangeException("Id must be positive integer number!");
            }

            var collar = this.DbSet.Where(x => x.Id == id).FirstOrDefault();

            return collar;
        }

        public Collar Get(string value)
        {
            throw new NotImplementedException();
        }

        public Collar Add(Collar item)
        {
            throw new NotImplementedException();
        }

        public void Delete(int id)
        {
            throw new NotImplementedException();
        }

        public void Update(int id, Collar item)
        {
            throw new NotImplementedException();
        }
    }
}